/**
 * 1、代码分类（位置）
 *  - 全局代码
 *  - 函数（局部）代码
 * 2. 全局执行上下文
 *  - 在执行全局代码前将window确定为全局执行上下文
 *  - 对全局数据进行预处理
 *      var定义的全局变量===>undefined，添加为window的属性
 *      function声明的全局函数===>赋值（fun），添加为window的方法
 *      this===>赋值（window）
 *  - 开始执行全局代码
 * 3. 函数执行上下文
 *  - 在调用函数，准备执行函数体之前，创建对应的函数执行上下文对象（虚拟的，存在于栈中）
 *  - 对局部数据进行预处理
 *      形参变量===>赋值（实参）===>添加为执行上下文的属性
 *      arguments===>赋值（实参列表），添加为执行上下文的属性
 *      var定义的局部变量===>undefined，添加为执行上下文的属性
 *      function声明的函数===>赋值（fun），添加为执行上下文的方法
 *      this===>赋值（调用函数的对象）
 *  - 开始执行函数体代码
 *
 * ----------------------------
 * 1. 在全局代码执行前，JS引擎就会创建一个栈来存储管理所有的执行上下文对象
 * 2. 在全局执行上下文（window）确定后，将其添加到栈中（压栈）
 * 3. 在函数执行上下文创建后，将其添加到栈中（压栈）
 * 4. 在当前函数执行完后，将栈顶的对象移出（出栈）
 * 5. 当所有代码执行完后，栈中只剩下window
 */

/* var a = 10;
var bar = function (x) {
  var b = 5;
  foo(x + b);
};

var foo = function (y) {
  var c = 5;
  console.log(a + c + y);
};

bar(10); */

// test
console.log("global begin:" + i); // global begin: undefined
var i = 1;

foo(1);

function foo(i) {
  if (i == 4) {
    return;
  }
  console.log("foo() begin:" + i); // foo() begin: 1 2 3
  foo(i + 1);
  console.log("foo() end:" + i); // foo() end: 3 2 1
}

console.log("global end:" + i); // global end: 1
